package cn.layfolk.uaa.service.impl;

import cn.hutool.json.JSONUtil;
import cn.layfolk.daimao.consts.ErrorCodeEnum;
import cn.layfolk.daimao.util.Webs;
import cn.layfolk.daimao.vo.respvo.ResponseVo;
import cn.layfolk.uaa.domain.TPermission;
import cn.layfolk.daimao.vo.TUser;
import cn.layfolk.uaa.mapper.TUserMapper;
import cn.layfolk.uaa.service.OauthClientDetailsService;
import cn.layfolk.uaa.service.TUserService;
import cn.layfolk.uaa.vo.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import javax.servlet.http.Cookie;
import java.io.UnsupportedEncodingException;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.TimeUnit;

@Service
public class TUserServiceImpl extends ServiceImpl<TUserMapper, TUser> implements TUserService {


    @Autowired
    private TUserMapper userMapper;
    @Autowired
    private OauthClientDetailsService oauthClientDetailsService;

    @Autowired
    private RedisTemplate redisTemplate;

    private static final String AUTHORIZATION_HEADER = "Authorization";


    /**
     * 登录操作
     */
    @Override
    public ResponseVo<UserLoginOutDto> login(UserLoginInDto inDto) {
        UserLoginOutDto loginOutDto = new UserLoginOutDto();
        ResponseVo outDto = new ResponseVo<>();

        // 1. 查询是否已经存在
        QueryWrapper<TUser> wrapper = new QueryWrapper<>();
        wrapper.eq("username", inDto.getUsername());
        TUser account = userMapper.selectOne(wrapper);

        if (account == null) {
            outDto.setStatusCode(ErrorCodeEnum.ACCOUNT_DOES_NOT_EXIST.getStatusCode());
            outDto.setMessage(ErrorCodeEnum.ACCOUNT_DOES_NOT_EXIST.getMessage());
            return outDto;
        }

        // 登录
        ClientModeLoginInDto loginInDto = new ClientModeLoginInDto();
        loginInDto.setClientId(inDto.getUsername()).setClientSecret(inDto.getPassword()).setScopes("all").setGrantType("client_credentials");
        ClientModeLoginOutDto clientModeLoginOutDto = oauthClientDetailsService.clientModeLogin(loginInDto);
        if (clientModeLoginOutDto.getStatusCode() != 200) {
            outDto.setMessage("登录失败");
            outDto.setStatusCode(401);
            return outDto;
        }
        loginOutDto.setAccessToken(clientModeLoginOutDto.getData().toString());

        // 查询该用户的权限
        List<TPermission> permions = queryClientPermission(account.getClientDetailsId());

        // 登录成功过后，将client_id: token token: info添加到Redis
        ClientInfoVo clientInfoVo = new ClientInfoVo();
        clientInfoVo.setUsername(inDto.getUsername());
        clientInfoVo.setTPermissions(permions);
        // 添加用户名
        clientInfoVo.setAccountName(account.getAccountName());
        clientInfoVo.setClientDetailsId(account.getClientDetailsId());
        loginOutDto.setAccountName(account.getAccountName());
        // 先删除
        String key = "account-" + inDto.getUsername();
        String accessToken = (String) redisTemplate.opsForValue().get(key);
        redisTemplate.delete(key);
        if (accessToken != null) {
            redisTemplate.delete(accessToken);
        }
        // 再添加
        redisTemplate.opsForValue().set(key, clientModeLoginOutDto.getData(), 7, TimeUnit.DAYS);
        redisTemplate.opsForValue().set(clientModeLoginOutDto.getData(), JSONUtil.toJsonStr(clientInfoVo), 7, TimeUnit.DAYS);

        Cookie cookie = new Cookie("daimao_access_token", clientModeLoginOutDto.getData().toString());
        cookie.setPath("/");
        // 一周有效期
        cookie.setMaxAge(604800);
        Webs.getResponse().addCookie(cookie);
        outDto.setData(loginOutDto);
        outDto.setMessage("登录成功");
        return outDto;
    }

    @Override
    public ResponseVo logout() throws UnsupportedEncodingException {
        ResponseVo responseVo = new ResponseVo();
        String header = Webs.getRequest().getHeader(AUTHORIZATION_HEADER);
        if (header == null) {
            responseVo.setData(false);
            responseVo.setMessage("你压根就没有带上请求头QAQ");
            responseVo.setStatusCode(401);
        } else {
            // 获取到传输的token
            String token = header.substring(header.indexOf(" ") + 1);
            // 解析token信息
            AccessTokenInfoDto accessInfo = oauthClientDetailsService.getAccessInfo();
            String key = "account-" + accessInfo.getClientId();
            String accessToken = (String) redisTemplate.opsForValue().get(key);
            redisTemplate.delete(key);
            if (!Objects.isNull(accessToken)) {
                redisTemplate.delete(accessToken);
            }
            redisTemplate.delete(token);
            responseVo.setMessage("好了你没了");
        }
        return responseVo;
    }

    private List<TPermission> queryClientPermission(Integer clientDetailId) {
        return userMapper.findPermissionsByUserId(clientDetailId);
    }
}
